package com.inspinia.base.util;

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by likun on 2016/10/25 0025.
 */
public class WordHelper {

    /**
     * 日志对象
     */
    private static Logger logger = LoggerFactory.getLogger(WordHelper.class);

    // word文档
    public Dispatch doc = null;
    // word运行程序对象
    private static ActiveXComponent word = null;
    // 所有word文档集合
    private static Dispatch documents = null;
    // 选定的范围或插入点
    private static Dispatch selection = null;
    // 设置是否保存后才退出的标志
    private boolean saveOnExit = true;
    /**
     * word中的当前文档
     */
    private static Dispatch document = null;
    // private static Dispatch textFrame = null;
    //
    /**
     * 所有表格
     */
    private Dispatch tables;
    /**
     * 当前表格
     */
    private Dispatch table;
    /**
     * 当前单元格
     */
    private Dispatch cell;
    /**
     * 当前表格中的所有行
     */
    private Dispatch rows;
    /**
     * 表格中的某一行
     */
    private Dispatch row;
    /**
     * 表格中的所有列
     */
    private Dispatch columns;
    /**
     * 表格中的某一列
     */
    private Dispatch column;
    /**
     * 打开word时同时要打开的文档，不指定时将新建一个空白文档
     */
    // private File openDoc;
    private static Dispatch shapes;
    private static Dispatch shape;
    private static Dispatch textRange;
    private static Dispatch textframe;
    private Dispatch range;
    private Dispatch paragraphs;
    private Dispatch paragraph;


    // constructor
    public WordHelper() {
        if (word == null) {
            word = new ActiveXComponent("Word.Application");
            word.setProperty("Visible", new Variant(false));
        }
        if (documents == null) {
            documents = word.getProperty("Documents").toDispatch();
        }
    }

    /**
     * 创建一个新的word文档
     */
    public void createNewDocument() {
        doc = Dispatch.call(documents, "Add").toDispatch();
        selection = Dispatch.get(word, "Selection").toDispatch();
    }

    /**
     * 打开一个已存在的文档
     *
     * @param docPath
     */
    public void openDocument(String docPath) {
        if (this.doc != null) {
            this.closeDocument();
        }
        doc = Dispatch.call(documents, "Open", docPath).toDispatch();
        selection = Dispatch.get(word, "Selection").toDispatch();
    }

    /**
     * 关闭当前word文档
     */
    public void closeDocument() {
        if (doc != null) {
            Dispatch.call(doc, "Save");
            Dispatch.call(doc, "Close", new Variant(saveOnExit));
            doc = null;
        }
    }

    /**
     * 关闭全部应用
     */
    public void close() {
        closeDocument();
        if (word != null) {
            Dispatch.call(word, "Quit");
            word = null;
        }
        selection = null;
        documents = null;
        ComThread.Release();
    }

    /**
     * 把插入点移动到文件首位置
     */
    public void moveStart() {
        if (selection == null)
            selection = Dispatch.get(word, "Selection").toDispatch();
        Dispatch.call(selection, "HomeKey", new Variant(6));
    }

    /**
     * 在当前插入点插入字符串
     *
     * @param newText 要插入的新字符串
     */
    public void insertText(String newText) {
        Dispatch.put(selection, "Text", newText);
    }

    /**
     * 在当前插入点插入图片
     *
     * @param imagePath 图片路径
     */
    public void insertImage(String imagePath) {
        Dispatch.call(Dispatch.get(selection, "InLineShapes").toDispatch(), "AddPicture", imagePath);
    }

    /**
     * 把选定的内容或者插入点向下移动
     *
     * @param pos 移动的距离
     */
    public void moveDown(int pos) {
        if (selection == null)
            selection = Dispatch.get(word, "Selection").toDispatch();
        for (int i = 0; i < pos; i++)
            Dispatch.call(selection, "MoveDown");
    }

    /**
     * 把选定的内容或插入点向上移动
     *
     * @param pos 移动的距离
     */
    public void moveUp(int pos) {
        if (selection == null)
            selection = Dispatch.get(word, "Selection").toDispatch();
        for (int i = 0; i < pos; i++)
            Dispatch.call(selection, "MoveUp");
    }

    /**
     * 把选定的内容或者插入点向左移动
     *
     * @param pos 移动的距离
     */
    public void moveLeft(int pos) {
        if (selection == null)
            selection = Dispatch.get(word, "Selection").toDispatch();
        for (int i = 0; i < pos; i++) {
            Dispatch.call(selection, "MoveLeft");
        }
    }

    /**
     * 把选定的内容或者插入点向右移动
     *
     * @param pos 移动的距离
     */
    public void moveRight(int pos) {
        if (selection == null)
            selection = Dispatch.get(word, "Selection").toDispatch();
        for (int i = 0; i < pos; i++)
            Dispatch.call(selection, "MoveRight");
    }

    /**
     * 文件保存或另存为
     *
     * @param savePath 一定要记得加上扩展名 .doc-temp 保存或另存为路径
     */
    public void save(String savePath) {
        Dispatch.call(
                (Dispatch) Dispatch.call(word, "WordBasic").getDispatch(),
                "FileSaveAs", savePath);
    }

 /*   *//**
     * 从第tIndex个Table中取出值第row行，第col列的值
     *
     * @param tableIndex 文档中的第tIndex个Table，即tIndex为索引取
     * @param cellRowIdx cell在Table第row行
     * @param cellColIdx cell在Talbe第col列
     * @return cell单元值
     * @throws Exception
     *//*
    public String getCellString(int tableIndex, int cellRowIdx, int cellColIdx)
            throws Exception {
//        // 所有表格
//        Dispatch tables = Dispatch.get(doc-temp, "Tables").toDispatch();
//        // 要取数据的表格
//        Dispatch table = Dispatch.call(tables, "Item", new Variant(tableIndex))
//                .toDispatch();
//        Dispatch cell = Dispatch.call(table, "Cell", new Variant(cellRowIdx),
//                new Variant(cellColIdx)).toDispatch();
//        Dispatch.call(cell, "Select");
//        return Dispatch.get(selection, "Text").getString();
        table=getTable(1);
        Dispatch cell=getCell(2,1);
        Dispatch.call(cell, "Select");
        return Dispatch.get(selection, "Text").getString();
    }

    *//**
     * 从第tableIndex个Table中取出值第cellRowIdx行，第cellColIdx列的值
     *
     * @param tableIndex 文档中的第tIndex个Table，即tIndex为索引取
     * @param cellRowIdx cell在Table第row行
     * @param cellColIdx cell在Talbe第col列
     * @return cell单元值
     * @throws Exception
     *//*
    public void getCellValue(int tableIndex, int cellRowIdx, int cellColIdx)
            throws Exception {
        // 所有表格
        Dispatch tables = Dispatch.get(doc-temp, "Tables").toDispatch();
        // 要取数据的表格
        Dispatch table = Dispatch.call(tables, "Item", new Variant(tableIndex))
                .toDispatch();
        Dispatch cell = Dispatch.call(table, "Cell", cellRowIdx, cellColIdx).toDispatch();
        Dispatch.call(cell, "Select");
        Dispatch.call(selection, "Copy");
    }*/

    /**
     * 获得指定的单元格里数据
     *
     * @param tableIndex
     * @param cellRowIdx
     * @param cellColIdx
     * @return
     */
    public String getTxtFromCell(int tableIndex, int cellRowIdx, int cellColIdx) {
        // 所有表格
        Dispatch tables = Dispatch.get(doc, "Tables").toDispatch();
        // 要填充的表格
        Dispatch table = Dispatch.call(tables, "Item", new Variant(tableIndex)).toDispatch();

        Dispatch rows = Dispatch.call(table, "Rows").toDispatch();

        Dispatch columns = Dispatch.call(table, "Columns").toDispatch();

        Dispatch cell = Dispatch.call(table, "Cell", new Variant(cellRowIdx), new Variant(cellColIdx)).toDispatch();
        Dispatch Range = Dispatch.get(cell, "Range").toDispatch();

//        System.out.println(Dispatch.get(Range,"Text").toString());

        Dispatch.call(cell, "Select");
        String ret = "";
        ret = Dispatch.get(selection, "Text").toString();
        ret = ret.substring(0, ret.length() - 2); // 去掉最后的回车符;
        return ret;
    }

    /**
     * 在当前光标处做粘贴
     */
    public void paste() {
        Dispatch.call(selection, "Paste");
    }

    /**
     * 在当前光标处添加图片
     *
     * @param imgPath 图片的地址
     */
    public void addImage(String imgPath) {
        if (imgPath != "" && imgPath != null) {
            Dispatch image = Dispatch.get(selection, "InLineShapes").toDispatch();
            Dispatch.call(image, "AddPicture", imgPath);
        }
    }

    /**
     * 在指定的单元格里填写数据
     *
     * @param tableIndex 文档中的第tIndex个Table，即tIndex为索引取
     * @param cellRowIdx cell在Table第row行
     * @param cellColIdx cell在Talbe第col列
     * @param txt        填写的数据
     */
    public void putTxtToCell(int tableIndex, int cellRowIdx, int cellColIdx,
                             String txt) {
        if (selection == null) {
            selection = Dispatch.get(word, "Selection").toDispatch();
        }
        // 所有表格
        Dispatch tables = Dispatch.get(doc, "Tables").toDispatch();
        // 要填充的表格
        Dispatch table = Dispatch.call(tables, "Item", new Variant(tableIndex))
                .toDispatch();
        Dispatch cell = Dispatch.call(table, "Cell", new Variant(cellRowIdx),
                new Variant(cellColIdx)).toDispatch();
        Dispatch.call(cell, "Select");
        Dispatch.put(selection, "Text", txt);
    }

    /**
     * 得到当前文档的tables集合
     */
    public Dispatch getTables() throws Exception {
        if (this.doc == null) {
            throw new Exception("there is not a document can't be operate!!!");
        }
        return Dispatch.get(doc, "Tables").toDispatch();
    }

    /**
     * 得到当前文档的表格数
     *
     * @param tables
     */
    public int getTablesCount(Dispatch tables) throws Exception {
        int count = 0;
        try {
            this.getTables();
        } catch (Exception e) {
            throw new Exception("there is not any table!!");
        }
        count = Dispatch.get(tables, "Count").toInt();
        return count;
    }

    /**
     * 在当前文档指定的位置拷贝表格
     *
     * @param pos        当前文档指定的位置
     * @param tableIndex 被拷贝的表格在word文档中所处的位置
     */
    public void copyTable(String pos, int tableIndex) {
        // 所有表格
        Dispatch tables = Dispatch.get(doc, "Tables").toDispatch();
        // 要填充的表格
        Dispatch table = Dispatch.call(tables, "Item", new Variant(tableIndex))
                .toDispatch();
        Dispatch range = Dispatch.get(table, "Range").toDispatch();
        Dispatch.call(range, "Copy");
        Dispatch textRange = Dispatch.get(selection, "Range").toDispatch();
        Dispatch.call(textRange, "Paste");
    }

    /**
     * 在当前文档指定的位置拷贝来自另一个文档中的表格
     *
     * @param anotherDocPath 另一个文档的磁盘路径
     * @param tableIndex     被拷贝的表格在另一格文档中的位置
     * @param pos            当前文档指定的位置
     */
    public void copyTableFromAnotherDoc(String anotherDocPath, int tableIndex,
                                        String pos) {
        Dispatch doc2 = null;
        try {
            doc2 = Dispatch.call(documents, "Open", anotherDocPath)
                    .toDispatch();
            // 所有表格
            Dispatch tables = Dispatch.get(doc2, "Tables").toDispatch();
            // 要填充的表格
            Dispatch table = Dispatch.call(tables, "Item",
                    new Variant(tableIndex)).toDispatch();
            Dispatch range = Dispatch.get(table, "Range").toDispatch();
            Dispatch.call(range, "Copy");
            Dispatch textRange = Dispatch.get(selection, "Range").toDispatch();
            moveDown(1);
            Dispatch.call(textRange, "Paste");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (doc2 != null) {
                Dispatch.call(doc2, "Close", new Variant(saveOnExit));
                doc2 = null;
            }
        }
    }

    /**
     * 在当前文档拷贝剪贴板数据
     *
     * @param pos
     */
    public void pasteExcelSheet(String pos) {
        moveStart();
        Dispatch textRange = Dispatch.get(selection, "Range").toDispatch();
        Dispatch.call(textRange, "Paste");
    }

    /**
     * 选中dispatch对象
     *
     * @param dispatch（分配，派遣）
     */
    private void select(Dispatch dispatch) {
        Dispatch.call(dispatch, "Select");
    }

    /**
     * 在当前文档指定的位置拷贝来自另一个文档中的图片
     *
     * @param anotherDocPath 另一个文档的磁盘路径
     * @param shapeIndex     被拷贝的图片在另一格文档中的位置
     * @param pos            当前文档指定的位置
     * @throws com.jacob.com.ComFailException Invoke of: Item Source: Microsoft Word 若shapeIndex不存在
     */
    public void copyImageFromAnotherDoc(String anotherDocPath, int shapeIndex, String pos) {
        Dispatch doc2 = null;
        try {
            doc2 = Dispatch.call(documents, "Open", anotherDocPath)
                    .toDispatch();
            Dispatch shapes = Dispatch.get(doc2, "InLineShapes").toDispatch();
            Dispatch shape = Dispatch.call(shapes, "Item",
                    new Variant(shapeIndex)).toDispatch();
            Dispatch imageRange = Dispatch.get(shape, "Range").toDispatch();
            Dispatch.call(imageRange, "Copy");
            Dispatch textRange = Dispatch.get(selection, "Range").toDispatch();
            moveDown(4);
            Dispatch.call(textRange, "Paste");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (doc2 != null) {
                Dispatch.call(doc2, "Close", new Variant(saveOnExit));
                doc2 = null;
            }
        }
    }

    /**
     * 打印当前word文档
     *
     * @throws Exception com.jacob.com.ComFailException: Invoke of: PrintOut Source:
     *                   Microsoft Word 若无打印机
     */
    public void printFile() {
        if (doc != null) {
            Dispatch.call(doc, "PrintOut");
        }
    }

    /**
     * 打印文本，反选，在文本后换行<br>
     * 警告：使用了Home, End来取消选中
     *
     * @param s
     */
    public void println(String s) {
        write(s);
        goToEnd();
        cmd("TypeParagraph");
    }

    /**
     * 执行某条宏指令
     *
     * @param cmd
     */
    private void cmd(String cmd) {
        Dispatch.call(selection, cmd);
    }

    /**
     * 按下Ctrl + End键
     */
    public void goToEnd() {
        Dispatch.call(selection, "EndKey", "6");
    }

    /**
     * 反选，再打印文本<br>
     * 警告：使用了Home, End来取消选中
     */
    public void print(String s) {
        goToEnd();
        write(s);
    }

    /**
     * 不反选, 直接输出文本
     *
     * @param s
     */
    public void write(String s) {
        Dispatch.put(selection, "Text", s);
    }

    /**
     * 反选，在文本后换行<br>
     * 警告：使用了Home, End来取消选中
     */
    public void println() {
        home();
        end();
        cmd("TypeParagraph");
    }

    /**
     * 按下Home键
     */
    public void home() {
        Dispatch.call(selection, "HomeKey", "5");
    }

    /**
     * 按下End键
     */
    public void end() {
        Dispatch.call(selection, "EndKey", "5");
    }

    /**
     * 按下Ctrl + Home键
     */
    public void goToBegin() {
        Dispatch.call(selection, "HomeKey", "6");
    }

    /**
     * 设置指定表格指定列的列宽
     *
     * @param tableIndex
     * @param columnWidth
     * @param columnIndex
     */
    public void setColumnWidth(int tableIndex, float columnWidth, int columnIndex) {
        this.getTable(tableIndex);
        this.setColumnWidth(columnWidth, columnIndex);
    }

    /**
     * 查找表
     *
     * @param tableIndex
     * @return
     */
    public Dispatch getTable(int tableIndex) {
        Dispatch tables = Dispatch.get(doc, "Tables").toDispatch();
        Dispatch table = Dispatch.call(tables, "Item", new Variant(tableIndex)).toDispatch();
        return table;
    }

    public Dispatch getShapes() throws Exception {
        return Dispatch.get(doc, "Shapes").toDispatch();
    }

    public int getShapesCount() throws Exception {
        int count = 0;
        count = Dispatch.get(shapes, "Count").toInt();
        return count;
    }

    public Dispatch getShape(int tIndex) throws Exception {
        return Dispatch.call(shapes, "Item", new Variant(tIndex)).toDispatch();
        // return Dispatch.invoke(shapes,"item",Dispatch.Method,new Object[]{
        // new Integer(tIndex)},new int[1]).toDispatch();
    }

    public Dispatch getTextFrame() throws Exception {
        return Dispatch.get(shape, "TextFrame").toDispatch();
    }

    public Dispatch getTextRange() throws Exception {
        return Dispatch.get(textframe, "TextRange").toDispatch();
    }

    /**
     * 设置当前表格指定列的列宽
     *
     * @param columnWidth
     * @param columnIndex 如果不是整齐的表格不能使用
     */
    public void setColumnWidth(float columnWidth, int columnIndex) {
        if (columnWidth < 11) {
            columnWidth = 120;
        }
        if (columns == null || column == null) {
            this.getColumns();
            this.getColumn(columnIndex);
        }
        Dispatch.put(column, "Width", new Variant(columnWidth));
    }

    /**
     * 设置指定表格指定列的背景色
     *
     * @param tableIndex
     * @param columnIndex
     * @param color       取值范围 0 < color < 17 默认：16 浅灰色 1：黑色 2：蓝色 3：浅蓝 ...............
     */
    public void setColumnBgColor(int tableIndex, int columnIndex, int color) {
        this.getTable(tableIndex);
        this.setColumnBgColor(columnIndex, color);
    }

    /**
     * 设置当前表格指定列的背景色
     *
     * @param columnIndex
     * @param color       取值范围 0 < color < 17 默认：16 浅灰色 1：黑色 2：蓝色 3：浅蓝 ...............
     */
    public void setColumnBgColor(int columnIndex, int color) {
        this.getColumn(columnIndex);
        Dispatch shading = Dispatch.get(column, "Shading").toDispatch();
        if (color > 16 || color < 1)
            color = 16;
        Dispatch.put(shading, "BackgroundPatternColorIndex", new Variant(color));
    }

    /**
     * 初始化 com 线程
     */
    public void initCom() {
        ComThread.InitSTA();
    }

    /**
     * 释放 com 线程资源 com 的线程回收不由 java 垃圾回收机制回收
     */
    public void releaseCom() {
        ComThread.Release();
    }

    /**
     * 设置当前表格指定行的背景色
     *
     * @param rowIndex
     * @param color    取值范围 0 < color < 17 默认：16 浅灰色 1：黑色 2：蓝色 3：浅蓝 ...............
     */
    public void setRowBgColor(int rowIndex, int color) {
        this.getRow(rowIndex);
        Dispatch shading = Dispatch.get(row, "Shading").toDispatch();
        if (color > 16 || color < 1)
            color = 16;
        Dispatch.put(shading, "BackgroundPatternColorIndex", new Variant(color));
    }

    /**
     * 设置指定表格的指定行的背景色
     *
     * @param tableIndex
     * @param rowIndex
     * @param color      取值范围 0 < color < 17 默认：16 浅灰色 1：黑色 2：蓝色 3：浅蓝 ...............
     */
    public void setRowBgColor(int tableIndex, int rowIndex, int color) {
        this.getTable(tableIndex);
        this.setRowBgColor(rowIndex, color);
    }

    /**
     * 设置当前选定内容的字体
     *
     * @param isBold      是否为粗体
     * @param isItalic    是否为斜体
     * @param isUnderLine 是否带下划线
     * @param color       rgb 字体颜色 例如：红色 255,0,0
     * @param size        字体大小 12:小四 16:三号
     * @param name        字体名称 例如：宋体，新宋体，楷体，隶书
     */
    public void setFont(boolean isBold, boolean isItalic, boolean isUnderLine,
                        String color, String size, String name) {
        Dispatch font = Dispatch.get(selection, "Font").toDispatch();
        Dispatch.put(font, "Name", new Variant(name));
        Dispatch.put(font, "Bold", new Variant(isBold));
        Dispatch.put(font, "Italic", new Variant(isItalic));
        Dispatch.put(font, "Underline", new Variant(isUnderLine));
        Dispatch.put(font, "Color", color);
        Dispatch.put(font, "Size", size);
    }

    /**
     * 恢复默认字体 不加粗，不倾斜，没下划线，黑色，小四号字，宋体
     */
    public void clearFont() {
        this.setFont(false, false, false, "0,0,0", "12", "宋体");
    }

    /**
     * 对当前段落进行格式化
     *
     * @param align     设置排列方式 默认：居左 0:居左 1:居中 2:居右 3:两端对齐 4:分散对齐
     * @param lineSpace 设置行间距 默认：1.0 0：1.0 1：1.5 2：2.0 3：最小值 4：固定值
     */
    public void setParaFormat(int align, int lineSpace) {
        if (align < 0 || align > 4) {
            align = 0;
        }
        if (lineSpace < 0 || lineSpace > 4) {
            lineSpace = 0;
        }
        Dispatch alignment = Dispatch.get(selection, "ParagraphFormat")
                .toDispatch();
        Dispatch.put(alignment, "Alignment", align);
        Dispatch.put(alignment, "LineSpacingRule", new Variant(lineSpace));
    }

    /**
     * 还原段落默认的格式 左对齐,行间距：1.0
     */
    public void clearParaFormat() {
        this.setParaFormat(0, 0);
    }

    /**
     * 创建表格
     *
     * @param pos     位置
     * @param numCols 列数
     * @param numRows 行数
     */
    public void createTable(String pos, int numCols, int numRows) {
        if (find(pos)) {
            Dispatch tables = Dispatch.get(doc, "Tables").toDispatch();
            Dispatch range = Dispatch.get(selection, "Range").toDispatch();
            Dispatch newTable = Dispatch.call(tables, "Add", range,
                    new Variant(numRows), new Variant(numCols)).toDispatch();
            setTableBorderWidth(newTable);//为表格添加边框
            Dispatch.call(selection, "MoveRight");
        }


    }

    /**
     * 在指定行前面增加行
     *
     * @param tableIndex word文件中的第N张表(从1开始)
     * @param rowIndex   指定行的序号(从1开始)
     */
    public void addTableRow(int tableIndex, int rowIndex) {
        // 所有表格
        Dispatch tables = Dispatch.get(doc, "Tables").toDispatch();
        // 要填充的表格
        Dispatch table = Dispatch.call(tables, "Item", new Variant(tableIndex))
                .toDispatch();
        // 表格的所有行
        Dispatch rows = Dispatch.get(table, "Rows").toDispatch();
        Dispatch row = Dispatch.call(rows, "Item", new Variant(rowIndex))
                .toDispatch();
        Dispatch.call(rows, "Add", new Variant(row));
    }

    /**
     * 在第1行前增加一行
     *
     * @param tableIndex word文档中的第N张表(从1开始)
     */
    public void addFirstTableRow(int tableIndex) {
        // 所有表格
        Dispatch tables = Dispatch.get(doc, "Tables").toDispatch();
        // 要填充的表格
        Dispatch table = Dispatch.call(tables, "Item", new Variant(tableIndex))
                .toDispatch();
        // 表格的所有行
        Dispatch rows = Dispatch.get(table, "Rows").toDispatch();
        Dispatch row = Dispatch.get(rows, "First").toDispatch();
        Dispatch.call(rows, "Add", new Variant(row));
    }

    /**
     * 在最后1行前增加一行
     *
     * @param tableIndex word文档中的第N张表(从1开始)
     */
    public void addLastTableRow(int tableIndex) {
        // 所有表格
        Dispatch tables = Dispatch.get(doc, "Tables").toDispatch();
        // 要填充的表格
        Dispatch table = Dispatch.call(tables, "Item", new Variant(tableIndex))
                .toDispatch();
        // 表格的所有行
        Dispatch rows = Dispatch.get(table, "Rows").toDispatch();
        Dispatch row = Dispatch.get(rows, "Last").toDispatch();
        Dispatch.call(rows, "Add", new Variant(row));
    }

    /**
     * 增加一行
     *
     * @param tableIndex word文档中的第N张表(从1开始)
     */
    public void addRow(int tableIndex) {
        Dispatch tables = Dispatch.get(doc, "Tables").toDispatch();
        // 要填充的表格
        Dispatch table = Dispatch.call(tables, "Item", new Variant(tableIndex))
                .toDispatch();
        // 表格的所有行
        Dispatch rows = Dispatch.get(table, "Rows").toDispatch();
        Dispatch.call(rows, "Add");
    }

    /**
     * 增加一列
     *
     * @param tableIndex word文档中的第N张表(从1开始)
     */
    public void addCol(int tableIndex) {
        // 所有表格
        Dispatch tables = Dispatch.get(doc, "Tables").toDispatch();
        // 要填充的表格
        Dispatch table = Dispatch.call(tables, "Item", new Variant(tableIndex))
                .toDispatch();
        // 表格的所有行
        Dispatch cols = Dispatch.get(table, "Columns").toDispatch();
        Dispatch.call(cols, "Add").toDispatch();
        Dispatch.call(cols, "AutoFit");
    }

    /**
     * 在指定列前面增加表格的列
     *
     * @param tableIndex word文档中的第N张表(从1开始)
     * @param colIndex   制定列的序号 (从1开始)
     */
    public void addTableCol(int tableIndex, int colIndex) {
        // 所有表格
        Dispatch tables = Dispatch.get(doc, "Tables").toDispatch();
        // 要填充的表格
        Dispatch table = Dispatch.call(tables, "Item", new Variant(tableIndex)).toDispatch();
        // 表格的所有行
        Dispatch cols = Dispatch.get(table, "Columns").toDispatch();
        System.out.println(Dispatch.get(cols, "Count"));
        Dispatch col = Dispatch.call(cols, "Item", new Variant(colIndex)).toDispatch();
        // Dispatch col = Dispatch.get(cols, "First").toDispatch();
        Dispatch.call(cols, "Add", col).toDispatch();
        Dispatch.call(cols, "AutoFit");
    }

    /**
     * 在第1列前增加一列
     *
     * @param tableIndex word文档中的第N张表(从1开始)
     */
    public void addFirstTableCol(int tableIndex) {
        Dispatch tables = Dispatch.get(doc, "Tables").toDispatch();
        // 要填充的表格
        Dispatch table = Dispatch.call(tables, "Item", new Variant(tableIndex)).toDispatch();
        // 表格的所有行
        Dispatch cols = Dispatch.get(table, "Columns").toDispatch();
        Dispatch col = Dispatch.get(cols, "First").toDispatch();
        Dispatch.call(cols, "Add", col).toDispatch();
        Dispatch.call(cols, "AutoFit");
    }

    /**
     * 在最后一列前增加一列
     *
     * @param tableIndex word文档中的第N张表(从1开始)
     */
    public void addLastTableCol(int tableIndex) {
        Dispatch tables = Dispatch.get(doc, "Tables").toDispatch();
        // 要填充的表格
        Dispatch table = Dispatch.call(tables, "Item", new Variant(tableIndex)).toDispatch();
        // 表格的所有行
        Dispatch cols = Dispatch.get(table, "Columns").toDispatch();
        Dispatch col = Dispatch.get(cols, "Last").toDispatch();
        Dispatch.call(cols, "Add", col).toDispatch();
        Dispatch.call(cols, "AutoFit");
    }

    /**
     * 从选定内容或插入点开始查找文本
     *
     * @param toFindText 要查找的文本
     * @return boolean true-查找到并选中该文本，false-未查找到文本
     */
    public boolean find(String toFindText) {
        if (toFindText == null || toFindText.equals(""))
            return false;
        // 从selection所在位置开始查询
        Dispatch find = word.call(selection, "Find").toDispatch();
        // 设置要查找的内容
        Dispatch.put(find, "Text", toFindText);
        // 向前查找
        Dispatch.put(find, "Forward", "True");
        // 设置格式
        Dispatch.put(find, "Format", "True");
        // 大小写匹配
        Dispatch.put(find, "MatchCase", "True");
        // 全字匹配
        Dispatch.put(find, "MatchWholeWord", "True");
        // 查找并选中
        return Dispatch.call(find, "Execute").getBoolean();
    }

    /**
     * 把选定选定内容设定为替换文本
     *
     * @param toFindText 查找字符串
     * @param newText    要替换的内容
     * @return
     */
    public boolean replaceText(String toFindText, String newText) {
        if (!find(toFindText))
            return false;
        Dispatch.put(selection, "Text", newText);
        return true;
    }

    /**
     * 全局替换文本
     *
     * @param toFindText 查找字符串
     * @param newText    要替换的内容
     */
    public void replaceAllText(String toFindText, String newText) {
        while (find(toFindText)) {
            Dispatch.put(selection, "Text", newText);
            Dispatch.call(selection, "MoveRight");
        }
    }

    /**
     * @param toFindText 要查找的字符串
     * @param imagePath  图片路径
     * @return 此函数将字符串替换成图片
     */
    public boolean replaceImage(String toFindText, String imagePath) {
        if (!find(toFindText))
            return false;
        Dispatch.call(Dispatch.get(selection, "InLineShapes").toDispatch(),
                "AddPicture", imagePath);
        return true;
    }

    /**
     * 全局替换图片
     *
     * @param toFindText 查找字符串
     * @param imagePath  图片路径
     */
    public void replaceAllImage(String toFindText, String imagePath) {
        while (find(toFindText)) {
            Dispatch.call(Dispatch.get(selection, "InLineShapes").toDispatch(),
                    "AddPicture", imagePath);
            Dispatch.call(selection, "MoveRight");
        }
    }

    /**
     * 设置当前表格线
     *
     * @param
     */
    public void setTableBorderWidth(Dispatch thisTable) {
//        if (w > 13 || w < 2) {
//            w = 6;
//        }

        // 设置表格线的粗细 1：代表最上边一条线 2：代表最左边一条线 3：最下边一条线 4：最右边一条线 5：除最上边最下边之外的所有横线
        // 6：除最左边最右边之外的所有竖线 7：从左上角到右下角的斜线 8：从左下角到右上角的斜线
        for (int i = 1; i < 7; i++) {
//            border = Dispatch.call(borders, "Item", new Variant(i)).toDispatch();
//            Dispatch.put(border, "LineWidth", new Variant(w));
//            Dispatch.put(border, "Visible", new Variant(true));
            Dispatch oBorders = Dispatch.call(thisTable, "Borders", 0 - i).toDispatch();
            Dispatch.put(oBorders, "LineStyle", new Variant(1));
        }
    }

    /**
     * 复制表的最后一行到剪切板
     *
     * @param
     */     /*
     * public void copyLastRow(int tableIndex) {
     * getRow(getRowsCount(tableIndex)); Dispatch.call(row, "select");
     * Dispatch.call(selection, "Copy"); }
     *
     * /** 复制表的最后一行并粘贴到下一行（包括行中的数据）
     *
     * @param tableIndex 表的索引 @param times 粘贴的次数
     */
     /*
     * public void duplicateLastRow(int tableIndex, int times) {
     * this.copyLastRow(tableIndex); for (int i = 0; i < times; i++) {
     * Dispatch.call(selection, "Paste"); } }
     *
     * /** 查找当前行表格所有行中的某一行
     *
     * @param rowIndex @return
     */
    public Dispatch getRow(int rowIndex) {
        if (rows == null)
            this.getRows();
        row = Dispatch.invoke(rows, "item", Dispatch.Method,
                new Object[]{new Integer(rowIndex)}, new int[1])
                .toDispatch();
        return row;
    }

    public int getRowsCount() {
        if (rows == null)
            this.getRows();
        return Dispatch.get(rows, "Count").getInt();
    }

    /**
     * 得到当前表格的所有的列
     *
     * @return
     */
    // 需要找到Dispatch对象,这里的Variant(1)不行一定要做成变量
    public Dispatch getColumns() {
        // this.getTables();
        Dispatch tables = Dispatch.get(doc, "Tables").toDispatch();
        Dispatch table = Dispatch.call(tables, "Item", new Variant(1))
                .toDispatch();
        return this.columns = Dispatch.get(table, "Columns").toDispatch();
    }

    /**
     * 得到当前表格的某一列
     *
     * @param columnIndex 列索引
     * @return
     */
    public Dispatch getColumn(int columnIndex) {
        if (columns == null)
            this.getColumns();
        return this.column = Dispatch.call(columns, "Item",
                new Variant(columnIndex)).toDispatch();
    }

    /**
     * 得到当前表格的列数
     *
     * @return
     */
    public int getColumnsCount() {
        this.getColumns();
        return Dispatch.get(columns, "Count").toInt();
    }

    /**
     * 得到指定表格的列数
     *
     * @param tableIndex
     * @return
     */
    public int getColumnsCount(int tableIndex) {
        this.getTable(tableIndex);
        return this.getColumnsCount();
    }

    /**
     * 得到表的行数
     *
     * @param tableIndex
     * @return
     */
    public int getRowsCount(int tableIndex) {
        this.getTable(tableIndex);
        return this.getRowsCount();
    }

    /**
     * 设置当前表格的所有行的行高
     *
     * @param rowHeight
     */
    public void setRowHeight(float rowHeight) {
        if (rowHeight > 0) {
            if (rows == null)
                this.getRows();
            Dispatch.put(rows, "Height", new Variant(rowHeight));
        }
    }

    /**
     * 设置指定表格的所有行的行高
     *
     * @param tableIndex
     * @param rowHeight
     */
    public void setRowHeight(int tableIndex, float rowHeight) {
        this.getRows(tableIndex);
        this.setRowHeight(rowHeight);
    }

    /**
     * 设置当前表格指定行的行高
     *
     * @param rowHeight
     * @param rowIndex
     */
    public void setRowHeight(float rowHeight, int rowIndex) {
        if (rowHeight > 0) {
            if (rows == null || row == null) {
                this.getRows();
                this.getRow(rowIndex);
            }
            Dispatch.put(row, "Height", new Variant(rowHeight));
        }
    }

    /**
     * 设置指定表格的指定行的行高
     *
     * @param tableIndex
     * @param rowHeight
     * @param rowIndex
     */
    public void setRowHeight(int tableIndex, float rowHeight, int rowIndex) {
        this.getTable(tableIndex);
        this.setRowHeight(rowHeight, rowIndex);
    }

    /**
     * 设置当前表格的所有列的列宽
     *
     * @param columnWidth 列宽 取值范围：10<columnWidth 默认值：120
     */
    public void setColumnWidth(float columnWidth) {
        if (columnWidth < 11) {
            columnWidth = 120;
        }
        if (columns == null)
            this.getColumns();
        Dispatch.put(columns, "Width", new Variant(columnWidth));
    }

    /**
     * 设置指定表格的所有列的列宽
     *
     * @param tableIndex
     * @param columnWidth
     */
    public void setColumnWidth(int tableIndex, float columnWidth) {
        this.getColumns(tableIndex);
        this.setColumnWidth(columnWidth);
    }

    /**
     * 得到指定表格的多有列
     *
     * @param tableIndex
     * @return
     */
    public Dispatch getColumns(int tableIndex) {
        getTable(tableIndex);
        return this.getColumns();
    }

    /**
     * 复制表的某一行
     *
     * @param tableIndex
     * @param rowIndex
     */
    public void copyRow(int tableIndex, int rowIndex) {
        getTable(tableIndex);
        getRows();
        row = getRow(rowIndex);
        Dispatch.call(row, "Select");
        Dispatch.call(selection, "Copy");
    }

    /**
     * 查找表的全部行
     *
     * @param tableIndex
     * @return
     */
    public Dispatch getRows(int tableIndex) {
        getTable(tableIndex);
        return this.getRows();
    }

    /**
     * 查找当前表的全部行
     *
     * @return
     */
    // 需要找到Dispatch对象,这里的Variant(1)不行一定要做成变量
    public Dispatch getRows() {
        Dispatch tables = Dispatch.get(doc, "Tables").toDispatch();
        Dispatch table = Dispatch.call(tables, "Item", new Variant(2))
                .toDispatch();
        rows = Dispatch.get(table, "rows").toDispatch();
        return rows;
    }

    /**
     * 查找指定表格的单元格
     *
     * @param tableIndex
     * @param cellRow
     * @param cellColumn
     * @return
     */
    public Dispatch getCell(int tableIndex, int cellRow, int cellColumn) {
        this.table = getTable(tableIndex);
        return getCell(cellRow, cellColumn);
    }

    /**
     * 设置指定表格指定单元格的宽度
     *
     * @param tableIndex
     * @param cellRow
     * @param cellColumn
     */
    public void setCellWidth(int tableIndex, int cellRow, int cellColumn, float columnWidth) {
        Dispatch cell = getCell(tableIndex, cellRow, cellColumn);
        Dispatch.put(cell, "Width", new Variant(columnWidth));
    }

    /**
     * 查找当前所在表的某单元格
     *
     * @param cellRow
     * @param cellColumn
     * @return
     * @throws Dispatch object expected
     */
    public Dispatch getCell(int cellRow, int cellColumn) {
        return cell = Dispatch.call(table, "Cell", new Variant(cellRow),
                new Variant(cellColumn)).toDispatch();
    }
    /**
     * 保存文档并退出程序
     *
     * @param fileName
     *            保存的文件名称
     * @param isSave
     *            是否保存修改
     * @throws Exception
     */
     /*
     * public void saveDocAndExit(File fileName, boolean isSave) throws
     * Exception { if (fileName != null) { if (!fileName.exists()) {
     * fileName.createNewFile(); } Dispatch wordBasic = (Dispatch)
     * Dispatch.call(word, "WordBasic").getDispatch();
     * Dispatch.invoke(wordBasic, "FileSaveAs", Dispatch.Method, new Object[] {
     * fileName.getPath(), new Variant(true), new Variant(false) }, new int[1]); }
     *
     * Dispatch.call(document, "Close", new Variant(isSave));
     * Dispatch.call(word, "Quit");
     *
     * word = null; documents = null; document = null; selection = null; }
     */

    /**
     * 合并当前表格指定的单元格 如果需要一次合并几个单元格只需要指出第一个单元格和最后一个单元格
     *
     * @param fstCellRowIndex 第一个单元格的行索引
     * @param fstCellColIndex 第一个单元格的列索引
     * @param secCellRowIndex 第二个单元格的行索引
     * @param secCellColIndex 第二个单元格的列索引
     */
    public void mergeCell(int fstCellRowIndex, int fstCellColIndex,
                          int secCellRowIndex, int secCellColIndex) {
        Dispatch fstCell = Dispatch.call(table, "Cell",
                new Variant(fstCellRowIndex), new Variant(fstCellColIndex))
                .toDispatch();
        Dispatch secCell = Dispatch.call(table, "Cell",
                new Variant(secCellRowIndex), new Variant(secCellColIndex))
                .toDispatch();
        Dispatch.call(fstCell, "Merge", secCell);
    }

    /**
     * 合并当前表格指定的列
     *
     * @param columnIndex 列索引
     */
    public void mergeColumn(int columnIndex) {
        this.getColumn(columnIndex);
        Dispatch cells = Dispatch.get(column, "Cells").toDispatch();
        Dispatch.call(cells, "Merge");
    }

    /**
     * 合并当前表格的指定的行
     *
     * @param rowIndex
     */
    public void mergeRow(int rowIndex) {
        this.getRow(rowIndex);
        Dispatch cells = Dispatch.get(row, "Cells").toDispatch();
        Dispatch.call(cells, "Merge");
    }

    /**
     * 合并指定表格的指定的行
     *
     * @param tableIndex
     * @param rowIndex   行索引
     */
    public void mergeRow(int tableIndex, int rowIndex) {
        this.getTable(tableIndex);
        this.mergeRow(rowIndex);
    }

    /**
     * 合并指定表格的指定的列
     *
     * @param tableIndex
     * @param columnIndex
     */
    public void mergeColumn(int tableIndex, int columnIndex) {
        this.getTable(tableIndex);
        this.mergeColumn(columnIndex);
    }

    /**
     * 合并指定表格的指定的单元格
     *
     * @param tableIndex
     * @param fstCellRowIndex
     * @param fstCellColIndex
     * @param secCellRowIndex
     * @param secCellColIndex
     */
    public void mergeCell(int tableIndex, int fstCellRowIndex,
                          int fstCellColIndex, int secCellRowIndex, int secCellColIndex) {
        this.getTable(tableIndex);
        this.mergeCell(fstCellRowIndex, fstCellColIndex, secCellRowIndex, secCellColIndex);
    }

    public Dispatch getRangeParagraphs() throws Exception {
        return Dispatch.get(range, "Paragraphs").toDispatch();
    }

    public Dispatch getParagraph(int tIndex) throws Exception {
        return Dispatch.call(paragraphs, "Item", new Variant(tIndex)).toDispatch();
    }

    public Dispatch getParagraphRange() throws Exception {
        return Dispatch.get(paragraph, "range").toDispatch();
    }

    public String getRangeText() throws Exception {
        return Dispatch.get(range, "Text").toString();
    }

    public int getParagraphsCount() throws Exception {
        int count = 0;
        count = Dispatch.get(paragraphs, "Count").toInt();
        return count;
    }

    /**
     * 打开文件
     *
     * @param inputDoc String 要打开的文件，全路径
     * @return Dispatch 打开的文件
     */
    public Dispatch open(String inputDoc) {
        return Dispatch.call(documents, "Open", inputDoc).toDispatch();
    }

    /**
     * 选定内容
     *
     * @return Dispatch 选定的范围或插入点
     */
    public Dispatch select() {
        return word.getProperty("Selection").toDispatch();
    }

    /**
     * 把插入点移动到文件首位置
     *
     * @param selection Dispatch 插入点
     */
    public void moveStart(Dispatch selection) {
        Dispatch.call(selection, "HomeKey", new Variant(6));
    }

    /**
     * 从选定内容或插入点开始查找文本
     *
     * @param selection  Dispatch 选定内容
     * @param toFindText String 要查找的文本
     * @return boolean true-查找到并选中该文本，false-未查找到文本
     */
    public boolean find(Dispatch selection, String toFindText) {
        //从selection所在位置开始查询
        Dispatch find = word.call(selection, "Find").toDispatch();
        //设置要查找的内容
        Dispatch.put(find, "Text", toFindText);
        //向前查找
        Dispatch.put(find, "Forward", "True");
        //设置格式
        Dispatch.put(find, "Format", "True");
        //大小写匹配
        Dispatch.put(find, "MatchCase", "True");
        //全字匹配
        Dispatch.put(find, "MatchWholeWord", "True");
        //查找并选中
        return Dispatch.call(find, "Execute").getBoolean();
    }

    /**
     * 把选定内容替换为设定文本
     *
     * @param selection Dispatch 选定内容
     * @param newText   String 替换为文本
     */
    public void replace(Dispatch selection, String newText) {
        //设置替换文本
        Dispatch.put(selection, "Text", newText);
    }

    /**
     * 全局替换
     *
     * @param selection  Dispatch 选定内容或起始插入点
     * @param oldText    String 要替换的文本
     * @param replaceObj String 替换为文本
     */
    public void replaceAll(Dispatch selection, String oldText, Object replaceObj) {
        //移动到文件开头
        moveStart(selection);
        if (replaceObj instanceof String) {
            String newText = (String) replaceObj;
            while (find(selection, oldText)) {
                replace(selection, newText);
                Dispatch.call(selection, "MoveRight");
            }
        }
    }

    /**
     * 保存文件
     *
     * @param outputPath String 输出文件（包含路径）
     */
//    public void save(String outputPath) {
////        Dispatch.call(Dispatch.call(word, "WordBasic").getDispatch(),
////                "FileSaveAs", outputPath);
//        Dispatch.call(doc-temp, "Save");
//    }

    /**
     * 关闭文件
     *
     * @param doc Dispatch 要关闭的文件
     */
    public void close(Dispatch doc) {
        Dispatch.call(doc, "Close", new Variant(saveOnExit));
    }

    /**
     * 根据模板、数据生成word文件
     *
     * @param inputPath String 模板文件（包含路径）
     * @param outPath   String 输出文件（包含路径）
     * @param data      HashMap 数据包（包含要填充的字段、对应的数据）
     */
    public void toWord(String inputPath, String outPath, HashMap data) {
        //将模板文件拷贝一份副本
        copyFile(inputPath, outPath);
        String oldText;
        Object newValue;
        try {
//            doc-temp = open(inputPath);
            doc = open(outPath);
            Dispatch selection = select();
            Iterator keys = data.keySet().iterator();
            while (keys.hasNext()) {
                oldText = (String) keys.next();
                newValue = data.get(oldText);
                replaceAll(selection, oldText, newValue);
            }
            close(doc);
            //清空没有传入的参数名
            clearPare(outPath, selection);
//            save(outPath);
        } catch (Exception e) {
            logger.error("操作word文件失败！" + e);
            e.printStackTrace();
        } finally {
            close();
            if (doc != null) {
                close(doc);
            }
        }
    }

    public void clearPare(String outPath, Dispatch selection) {
        Dispatch targetDoc = open(outPath);
        //将文档保存为text
        String tempFile = saveAsTxt(targetDoc, outPath);
        close(targetDoc);
        //将文本文件读取成字符串
        String text = txtToString(tempFile);
        deleteFile(tempFile);
        doc = open(outPath);
        selection = select();
        //匹配并替换没有传入的参数
        clear(text, selection);
    }

    private void clear(String text, Dispatch selection) {
        if (text != null) {
            Pattern p = Pattern.compile("\\$\\{(.*?)}");
            Matcher m = p.matcher(text);
            while (m.find()) {
                String oldText = "${" + m.group(1) + "}";
                System.out.println(oldText);
                replaceAll(selection, oldText, "");
            }
        }
    }

    private void deleteFile(String tempFile) {
        File file = new File(tempFile);
        if (file.exists()) {
            file.delete();
        }
    }

    /**
     * 将文本文件读取成字符串
     *
     * @param file
     */
    private String txtToString(String file) {
        File temp = new File(file);
        FileInputStream fis = null;
        if (temp.exists()) {
            try {
                fis = new FileInputStream(temp);
                BufferedReader tBufferedReader = new BufferedReader(new InputStreamReader(fis, "GBK"));
                StringBuffer tStringBuffer = new StringBuffer();
                String sTempOneLine = new String("");
                while ((sTempOneLine = tBufferedReader.readLine()) != null) {
                    tStringBuffer.append(sTempOneLine);
                }
                tBufferedReader.close();
                return tStringBuffer.toString();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                return null;
            } catch (IOException e) {
                e.printStackTrace();
                return null;
            } finally {
                try {
                    if (fis != null) {
                        fis.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    /**
     * 将文档保存为text
     *
     * @param doc
     * @param outPath
     */
    private String saveAsTxt(Dispatch doc, String outPath) {
        String tempFile = outPath + System.currentTimeMillis() + ".txt";
        Dispatch.invoke(doc, "SaveAs", Dispatch.Method, new Object[]{
                tempFile, new Variant(7)
        }, new int[1]);
        return tempFile;
    }

    /**
     * 拷贝文件副本
     *
     * @param inputPath
     * @param outPath
     */
    public void copyFile(String inputPath, String outPath) {
        //如果文件夹不存在则生成文件夹
        creadFolder(outPath);
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream(inputPath);
            fos = new FileOutputStream(outPath);
            byte[] buffer = new byte[1024];
            int len;
            while ((len = fis.read(buffer)) != -1) {
                fos.write(buffer, 0, len);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fis != null) {
                    fis.close();
                }
                if (fos != null) {
                    fos.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }

    }

    /**
     * 输出文件夹的文件如果不存在则生成文件夹
     *
     * @param outPath
     */
    private void creadFolder(String outPath) {
        File folder = new File(new File(outPath).getParent());
        if (!folder.exists()) {
            folder.mkdirs();
        }
    }

    public void printing(String inPath, String outPath, HashMap map) {

        toWord(inPath, outPath, map);

//        ActiveXComponent objWord = new ActiveXComponent("Word.Application");
//        Dispatch wordObject = (Dispatch) objWord.getObject();
//        Dispatch.put((Dispatch) wordObject, "Visible", new Variant(false));
//        Dispatch documents = objWord.getProperty("Documents").toDispatch();
//        Dispatch document = Dispatch.call(documents, "Open", outPath).toDispatch();
//
//        Dispatch.call(document, "PrintOut");
//
//        Dispatch.call(document, "Close", new Variant(false));
//        objWord.invoke("Quit",new Variant[0]);
        word.invoke("Quit", new Variant[0]);
        //关闭com的线程
        ComThread.Release();
    }

    /**
     * 检测文件的路径是否存在,若不存在就创建
     *
     * @param targetFilePath
     */
    public void mkdir(String targetFilePath) {
        File file = new File(targetFilePath);
        String dir = file.getParent();
        File dirFile = new File(dir);
        if (!dirFile.exists()) {
            dirFile.mkdirs();
        }
    }

    /**
     * 在文档最后插入分页符
     */
    public void insertNewPageToEnd() {
        if (selection == null) {
            selection = Dispatch.get(word, "Selection").toDispatch();
        }
        goToEnd();
        Dispatch.call(selection, "InsertBreak", new Variant(7));
    }

    /**
     * 删除表格的某一行
     *
     * @param tableIndex
     * @param rowIndex
     */
    public void deleteTableRow(int tableIndex, int rowIndex) {
        table = getTable(tableIndex);
        Dispatch row = getRow(rowIndex);
        Dispatch.call(row, "Delete");
    }

    /**
     *  *Variant(0):doc-temp
             *Variant(1):dot
             *Variant(2-5)，Variant(7):txt
             *Variant(6):rft
             *Variant(8)，Variant(10):htm
             *Variant(9):mht
             *Variant(11)，Variant(19-22):xml
             *Variant(12):docx
             *Variant(13):docm
             *Variant(14):dotx
             *Variant(15):dotm
             *Variant(16)、Variant(24):docx
             *Variant(17):pdf
             *Variant(18):xps
             *Variant(23):odt
     * @param doc
     * @param outPath
     */
    public void saveAsDocx(Dispatch doc, String outPath){
        Dispatch.invoke(doc, "SaveAs", Dispatch.Method, new Object[]{
                outPath, new Variant(12)
        }, new int[1]);
    }

    public static String xml2Docx(String xmlPath){
        WordHelper wordUtil=new WordHelper();
        try {
            Dispatch targetDoc = wordUtil.open(xmlPath);
            String docxPath=xmlPath.substring(0,xmlPath.lastIndexOf("."))+".docx";
            wordUtil.saveAsDocx(targetDoc,docxPath);
            wordUtil.close();
            wordUtil.deleteFile(xmlPath);
            return xmlPath;
        } catch (Exception e){
            wordUtil.close();
            logger.error("xml转docx失败",e);
            return null;
        }
    }

/********************************************************************************************************************/
    /**
     * 根据模板文件创建文件
     *
     * @param param           参数 HashMap
     * @param templetFilePath 模板文件路径
     * @param targetFilePath  生成的目标文件路径
     * @return
     */
    public static boolean createWord(Map<String, Object> param, String templetFilePath, String targetFilePath) {
        String inPath = templetFilePath;
        String outPath = targetFilePath;
        try {
            WordHelper app = new WordHelper();
            app.mkdir(outPath);
            app.printing(inPath, outPath, (HashMap) param);
            return true;
        } catch (Exception e) {
            logger.error("生成word文件失败",e);
            e.printStackTrace();
            return false;
        }
    }
/********************************************************************************************************************/

/**
 * 填充案件处置通知书数据
 */
public void addCaseData(ArrayList<HashMap<String, String>> bankData) throws Exception {
    if (bankData.size() <= 5) {  //涉案账号
        setCaseHandlePageValue(bankData);
    } else {  //新建第二页填充多余的数据
        setCaseHandlePageValue(bankData);//案件处置数据

        insertNewPageToEnd();//在文档最后插入新的一页
        insertText("96110警情处置登记表(副页)\r\n");
        setFont(true, false, false, "0,0,0", "16", "仿宋_GB2312");
        setParaFormat(0,0);//放在那句话后面 就作用于那句话
        goToBegin();
        goToEnd();

        /*添加表格*/
        insertText("${table}");
        goToBegin();
        createTable("${table}", 10, bankData.size() + 4 +1);
        table = getTable(2);
        int rowLength = getRowsCount(2);
        mergeCell(1, 1, 1, 2);
        mergeCell(1, 2, 1, 4);
        mergeCell(1, 3, 1, 4);
        mergeCell(1, 4, 1, 6);
        for (int i = 2; i < 9; i++) {
            mergeCell(i, 3, i, 4);
            mergeCell(i, 4, i, 5);
            mergeCell(i, 5, i, 6);
        }
        for(int i = 9;i < rowLength; i++){
            mergeCell(i, 3, i, 4);
            mergeCell(i,4, i, 6);
            mergeCell(i,5, i, 7);
        }
        mergeCell(2, 1, 8, 1);
        mergeCell(9, 1,14, 1);
        mergeCell(rowLength, 2,rowLength, 10);
        //为表格的固定位置设置内容
        putTxtToCell(2,1,1,"受理单位");
        putTxtToCell(2,1,3,"接警编号");
        String cellValue = null;
        //填充第二页的案件处置通知书数据
        putTxtToCell(2,2,1,"涉\n"+
                "案\n" +
                "资\n" +
                "金\n" +
                "流\n");
        putTxtToCell(2,9,1,"涉\n"+
                "案\n" +
                "信\n" +
                "息\n" +
                "流\n");
        putTxtToCell(2,rowLength,1,"备\n"+
                "注\n"
        );
        for (int i = 4; i < bankData.size(); i++) {
            HashMap<String, String> phoneInfo = bankData.get(i);
            putTxtToCell(2, i - 2, 2, phoneInfo.get("bank"));
            putTxtToCell(2, i - 2, 3, phoneInfo.get("acount"));
            putTxtToCell(2, i - 2, 4, phoneInfo.get("money"));
            putTxtToCell(2, i - 2, 5, phoneInfo.get("retroaction"));
            putTxtToCell(2, i - 2, 6, phoneInfo.get("CUP"));
            putTxtToCell(2, i - 2, 7, phoneInfo.get("check"));
        }
        for (int i = 4; i < bankData.size(); i++) {
            HashMap<String, String> phoneInfo = bankData.get(i);
            putTxtToCell(2, i +6, 2, phoneInfo.get("operator"));
            putTxtToCell(2, i +6, 3, phoneInfo.get("number"));
            putTxtToCell(2, i +6, 4, phoneInfo.get("msg"));
            putTxtToCell(2, i +6, 5, phoneInfo.get("threeRe"));
        }
        cellValue = getTxtFromCell(1, 4, 1);
        putTxtToCell(2,1,2,"  "+cellValue);
        cellValue = getTxtFromCell(1, 5, 3);
        putTxtToCell(2,1,4,"  "+cellValue);
        cellValue = getTxtFromCell(1, 15, 2);
        putTxtToCell(2,9,2,"  "+cellValue);
        cellValue = getTxtFromCell(1, 15, 3);
        putTxtToCell(2,9,3,"  "+cellValue);
        cellValue = getTxtFromCell(1, 15, 4);
        putTxtToCell(2,9,4,"  "+cellValue);
        cellValue = getTxtFromCell(1, 15, 5);
        putTxtToCell(2,9,5,"  "+cellValue);
        cellValue = getTxtFromCell(1, 5, 3);
        putTxtToCell(2,1,4,"  "+cellValue);
    }
}
    /**
     * 设置案件处置通知书第一页涉案数据
     *
     * @param phoneData
     */
    private void setCaseHandlePageValue(ArrayList<HashMap<String, String>> phoneData) {
        for (int i = 0; i < (phoneData.size()>6?6:phoneData.size()); i++) {
            HashMap<String, String> phoneInfo = phoneData.get(i);
            putTxtToCell(1, i+9, 2, phoneInfo.get("bank"));
            putTxtToCell(1, i+9, 3, phoneInfo.get("acount"));
            putTxtToCell(1, i+9, 4, phoneInfo.get("money"));
            putTxtToCell(1, i+9, 5, phoneInfo.get("retroaction"));
            putTxtToCell(1, i+9, 6, phoneInfo.get("CUP"));
            putTxtToCell(1, i+9, 7, phoneInfo.get("check"));
        }
        for (int i = 0; i < (phoneData.size()>4?4:phoneData.size()); i++) {
            HashMap<String, String> phoneInfo = phoneData.get(i);
            putTxtToCell(1, i+16, 2, phoneInfo.get("operator"));
            putTxtToCell(1, i+16, 3, phoneInfo.get("number"));
            putTxtToCell(1, i+16, 4, phoneInfo.get("msg"));
            putTxtToCell(1, i+16, 5, phoneInfo.get("threeRe"));
        }
    }


    /**
     * 填充第三方支付通知书数据
     */
    public void addThordPayData(ArrayList<HashMap<String, String>> payData) throws Exception {
        if (payData.size() <= 5) {  //涉案账号
            setThordPayPageValue(payData);
        }else {  //新建第二页填充多余的数据
            setThordPayPageValue(payData);//涉案账号
            insertNewPageToEnd();//在文档最后插入新的一页
            insertText("协助快速处置（冻结）第三方支付公司账户通知书（副页）\r\n");
            setFont(true, false, false, "0,0,0", "16", "仿宋_GB2312");
            setParaFormat(1,1);
            goToBegin();
            goToEnd();
        /*添加表格*/
            insertText("${table}");
            goToBegin();
            createTable("${table}", 10, payData.size() + 4 - 5);
            table = getTable(2);
            int rowLength = getRowsCount(2);
            mergeCell(1, 1, 1, 2);
            mergeCell(1, 2, 1, 4);
            mergeCell(1, 3, 1, 4);
            mergeCell(1, 4, 1, 6);
            for (int i = 2; i < rowLength-1; i++) {
                mergeCell(i, 2, i, 3);
                mergeCell(i, 2, i, 3);
                mergeCell(i, 3, i, 4);
                mergeCell(i, 4, i, 5);
                mergeCell(i, 5, i, 6);
           }
            mergeCell(rowLength - 1, 2, rowLength - 1, 10);
            mergeCell(rowLength, 1, rowLength, 10);
            //为表格的固定位置设置内容
            putTxtToCell(2,1,1,"接警编号");
            String cellValue = getTxtFromCell(1, 3, 2);
            //填充第二页第三方支付的数据
            for (int i = 5; i < payData.size(); i++) {
                HashMap<String, String> phoneInfo = payData.get(i);
                putTxtToCell(2, i - 2, 1, phoneInfo.get("id"));
                putTxtToCell(2, i - 2, 2, phoneInfo.get("acount"));
                putTxtToCell(2, i - 2, 3, phoneInfo.get("type"));
                putTxtToCell(2, i - 2, 4, phoneInfo.get("time"));
                putTxtToCell(2, i - 2, 5, phoneInfo.get("desc"));
            }
//            cellValue = getTxtFromCell(1, 10, 1);
//            putTxtToCell(2,rowLength-1,1,"  "+cellValue);
              putTxtToCell(2,rowLength-1,1,"处\n" +
                    "置\n" +
                    "措\n" +
                    "施\n" +
                    "名\n" +
                    "称\n");
            cellValue = getTxtFromCell(1, 10, 2);
            putTxtToCell(2,rowLength-1,2,"  "+cellValue);
            cellValue = getTxtFromCell(1, 11, 1);
            putTxtToCell(2,rowLength,1,"  "+cellValue);
            putTxtToCell(2,1,1,"受理单位");
            putTxtToCell(2,1,3,"接警编号");
            cellValue = getTxtFromCell(1, 4, 1);
            putTxtToCell(2,2,1,cellValue);
            cellValue = getTxtFromCell(1, 2, 2);
            putTxtToCell(2,1,4,cellValue);
            cellValue = getTxtFromCell(1, 3, 1);
            putTxtToCell(2,1,2,cellValue);
            cellValue = getTxtFromCell(1, 3, 2);
            putTxtToCell(2,2,2,cellValue);
            cellValue = getTxtFromCell(1, 4, 2);
            putTxtToCell(2,2,2,cellValue);
            cellValue = getTxtFromCell(1, 4, 3);
            putTxtToCell(2,2,3,cellValue);
            cellValue = getTxtFromCell(1, 4, 4);
            putTxtToCell(2,2,4,cellValue);
            cellValue = getTxtFromCell(1, 4, 5);
            putTxtToCell(2,2,5,cellValue);
        }
    }
    /**
     * 填充银行卡通知书数据
     * @param bankData
     */
    public void addBankData(ArrayList<HashMap<String, String>> bankData) throws Exception {
        if (bankData.size() <= 5) {  //涉案资金流号码
            setBankOnePageValue(bankData);
        } else {  //新建第二页填充多余的数据
            setBankOnePageValue(bankData);//涉案资金流号码

            insertNewPageToEnd();//在文档最后插入新的一页
            insertText("协助快速处置（冻结）银行资金账户通知书(副页)\r\n");
            setFont(true, false, false, "0,0,0", "16", "仿宋_GB2312");
            setParaFormat(0,1);
            goToBegin();
            goToEnd();

        /*添加表格*/
            insertText("${table}");
            goToBegin();
            createTable("${table}", 10, bankData.size() + 4 - 5);
            table = getTable(2);
            int rowLength = getRowsCount(2);
            mergeCell(1, 1, 1, 2);
            mergeCell(1, 2, 1, 4);
            mergeCell(1, 3, 1, 4);
            mergeCell(1, 4, 1, 6);
            for (int i = 2; i < rowLength-1; i++) {
                mergeCell(i, 2, i, 5);
                mergeCell(i, 3, i, 5);
                mergeCell(i, 4, i, 5);
            }
            mergeCell(rowLength - 1, 2, rowLength - 1, 10);
            mergeCell(rowLength, 1, rowLength, 10);
            //为表格的固定位置设置内容
            putTxtToCell(2,1,1,"接警编号");
            String cellValue = getTxtFromCell(1, 3, 2);
            //填充第二页的银行卡数据
            for (int i = 5; i < bankData.size(); i++) {
                HashMap<String, String> phoneInfo = bankData.get(i);
                putTxtToCell(2, i - 2, 1, phoneInfo.get("id"));
                putTxtToCell(2, i - 2, 2, phoneInfo.get("number"));
                putTxtToCell(2, i - 2, 3, phoneInfo.get("time"));
                putTxtToCell(2, i - 2, 4, phoneInfo.get("desc"));
            }

            putTxtToCell(2,rowLength-1,1,"处\n" +
                    "置\n" +
                    "措\n" +
                    "施\n" +
                    "名\n" +
                    "称\n");
            cellValue = getTxtFromCell(1, 10, 2);
            putTxtToCell(2,rowLength-1,2,"  "+cellValue);
            cellValue = getTxtFromCell(1, 11, 1);
            putTxtToCell(2,rowLength,1,"  "+cellValue);
            putTxtToCell(2,1,1,"受理单位");
            putTxtToCell(2,1,3,"接警编号");
            cellValue = getTxtFromCell(1, 4, 1);
            putTxtToCell(2,2,1,cellValue);
            cellValue = getTxtFromCell(1, 4, 2);
            putTxtToCell(2,2,2,cellValue);
            cellValue = getTxtFromCell(1, 4, 3);
            putTxtToCell(2,2,3,cellValue);
            cellValue = getTxtFromCell(1, 4, 4);
            putTxtToCell(2,2,4,cellValue);
            cellValue = getTxtFromCell(1, 2, 2);
            putTxtToCell(2,1,4,cellValue);
            cellValue = getTxtFromCell(1, 3, 1);
            putTxtToCell(2,1,2,cellValue);

        }
    }

    /**
     * 填充信息流通知书电话号码
     *
     * @param phoneData
     */
    public void addPhoneData(ArrayList<HashMap<String, String>> phoneData) throws Exception {
        if (phoneData.size() <= 5) {  //在第一页填充数据
            setInfoOnePageValue(phoneData);
        } else {  //新建第二页填充多余的数据
            setInfoOnePageValue(phoneData);//填充第一页的电话号码数据

            insertNewPageToEnd();//在文档最后插入新的一页
            insertText("协助快速处置信息流通知书（副页）\r\n");
            setFont(true, false, false, "0,0,0", "16", "仿宋_GB2312");
            setParaFormat(1,1);
            goToBegin();
            goToEnd();

        /*添加表格*/
            insertText("${table}");
            goToBegin();
            createTable("${table}", 10, phoneData.size() + 4 - 5);
            table = getTable(2);
            mergeCell(1, 1, 1, 2);
            mergeCell(1, 2, 1, 4);
            mergeCell(1, 3, 1, 4);
            mergeCell(1, 4, 1, 6);
            int rowLength = getRowsCount(2);
            for (int i = 2; i < rowLength-1; i++) {
                mergeCell(i, 2, i, 5);
                mergeCell(i, 3, i, 5);
                mergeCell(i, 4, i, 5);
            }
            mergeCell(rowLength - 1, 2, rowLength - 1, 10);
            mergeCell(rowLength, 1, rowLength, 10);

        //为表格的固定位置设置内容
            putTxtToCell(2,1,1,"受理单位");
            String cellValue = getTxtFromCell(1, 3, 2);
            putTxtToCell(2,1,2,cellValue);
            putTxtToCell(2,1,3,"接警编号");
            cellValue = getTxtFromCell(1, 4, 2);
            putTxtToCell(2,1,4,cellValue);
            putTxtToCell(2,2,1,"序号");
            putTxtToCell(2,2,2,"号码");
            putTxtToCell(2,2,3,"起止时间");
            putTxtToCell(2,2,4,"备注");

            //填充第二页的电话数据
            for (int i = 5; i < phoneData.size(); i++) {
                HashMap<String, String> phoneInfo = phoneData.get(i);
                putTxtToCell(2, i - 2, 1, phoneInfo.get("id"));
                putTxtToCell(2, i - 2, 2, phoneInfo.get("phone"));
                putTxtToCell(2, i - 2, 3, phoneInfo.get("time"));
                putTxtToCell(2, i - 2, 4, phoneInfo.get("desc"));
            }

            putTxtToCell(2,rowLength-1,1,"处\n" +
                    "置\n" +
                    "措\n" +
                    "施\n" +
                    "名\n" +
                    "称\n");
            cellValue = getTxtFromCell(1, 12, 2);
            putTxtToCell(2,rowLength-1,2,"  "+cellValue);
            cellValue = getTxtFromCell(1, 13, 1);
            putTxtToCell(2,rowLength,1,cellValue);
        }
    }
/**
 * 设置第三方支付通知书第一页涉案数据
 *
 * @param phoneData
 */
private void setThordPayPageValue(ArrayList<HashMap<String, String>> phoneData) {
    for (int i = 0; i < (phoneData.size()>5?5:phoneData.size()); i++) {
        HashMap<String, String> phoneInfo = phoneData.get(i);
        putTxtToCell(1, i+5, 2, phoneInfo.get("acount"));
        putTxtToCell(1, i+5, 3, phoneInfo.get("type"));
        putTxtToCell(1, i+5, 4, phoneInfo.get("time"));
        putTxtToCell(1, i+5, 5, phoneInfo.get("desc"));
    }
}
    /**
     *设置银行卡通知书第一页涉案资金流
     */
private void setBankOnePageValue(ArrayList<HashMap<String, String>> phoneData) {
    for (int i = 0; i < (phoneData.size()>5?5:phoneData.size()); i++) {
        HashMap<String, String> phoneInfo = phoneData.get(i);
        putTxtToCell(1, i+5, 2, phoneInfo.get("number"));
        putTxtToCell(1, i+5, 3, phoneInfo.get("time"));
        putTxtToCell(1, i+5, 4, phoneInfo.get("desc"));
    }
}
    /**
     * 设置信息流通知书第一页电话号码的值
     *
     * @param phoneData
     */
    private void setInfoOnePageValue(ArrayList<HashMap<String, String>> phoneData) {
        for (int i = 0; i < (phoneData.size()>5?5:phoneData.size()); i++) {
            HashMap<String, String> phoneInfo = phoneData.get(i);
            putTxtToCell(1, i + 7, 1, phoneInfo.get("id"));
            putTxtToCell(1, i + 7, 2, phoneInfo.get("phone"));
            putTxtToCell(1, i + 7, 3, phoneInfo.get("time"));
            putTxtToCell(1, i + 7, 4, phoneInfo.get("desc"));
        }
    }
/********************************************************************************************************************/


    /**
     * 填充警情处理通知书的内容
     *
     * @param data
     */
    public void addAlarmData(HashMap<String, Object> data) {

        ArrayList<HashMap<String, String>> alarmBankData = (ArrayList<HashMap<String, String>>) data.get("${alarmBankData}");
        ArrayList<HashMap<String, String>> alarmInfoData = (ArrayList<HashMap<String, String>>) data.get("${alarmInfoData}");

        //填充第一页的数据
        for (int i = 0; i < (alarmBankData.size() > 6 ? 6 : alarmBankData.size()); i++) {
            HashMap<String, String> alarmBankInfo = alarmBankData.get(i);
            putTxtToCell(1, 9 + i, 2, alarmBankInfo.get("bank_name"));
            putTxtToCell(1, 9 + i, 3, alarmBankInfo.get("bank_number"));
            putTxtToCell(1, 9 + i, 5, alarmBankInfo.get("bank_fruit"));
            putTxtToCell(1, 9 + i, 4, alarmBankInfo.get("bank_money"));
            putTxtToCell(1, 9 + i, 6, alarmBankInfo.get("CUP"));
            putTxtToCell(1, 9 + i, 7, alarmBankInfo.get("chaKong"));
        }
        for (int i = 0; i < (alarmInfoData.size() > 4 ? 4 : alarmInfoData.size()); i++) {
            HashMap<String, String> alarmInfo = alarmInfoData.get(i);
            putTxtToCell(1, i + 16, 2, alarmInfo.get("info_name"));
            putTxtToCell(1, i + 16, 3, alarmInfo.get("phone_number"));
            putTxtToCell(1, i + 16, 4, alarmInfo.get("info_fruit"));
            putTxtToCell(1, i + 16, 5, alarmInfo.get("three_fruit"));
        }
        int tableRowCount = 4;
        int bankRowCount = 0;
        int infoRowCount = 0;
        if (alarmBankData.size() > 6) {
            bankRowCount = alarmBankData.size() - 6;
            tableRowCount += bankRowCount;
        }
        if (alarmInfoData.size() > 4) {
            infoRowCount = alarmInfoData.size() - 4;
            tableRowCount += infoRowCount;
        }

        if (bankRowCount == 0 && infoRowCount == 0) {
            return;
        }

        if (bankRowCount == 0 || infoRowCount == 0) {
            tableRowCount -= 1;
        }

        selection = Dispatch.get(word, "Selection").toDispatch();
        goToEnd();
        insertText("96110警情处置登记表(副页)\r\n");
        goToBegin();
        goToEnd();

        /*添加表格*/
        insertText("${table}");
        goToBegin();
        createTable("${table}", 13, tableRowCount);
        table = getTable(2);

        //表格第一行
        mergeCell(1, 1, 1, 2);
        mergeCell(1, 2, 1, 4);
        mergeCell(1, 3, 1, 4);
        mergeCell(1, 4, 1, 9);

        goToBegin();
        String cellValue = getTxtFromCell(1, 2, 2);
        putTxtToCell(2, 1, 1, "接警编号");
        putTxtToCell(2, 1, 2, cellValue);
        putTxtToCell(2, 1, 3, "处置民警");
        cellValue = getTxtFromCell(1, 2, 4);
        putTxtToCell(2, 1, 4, cellValue);

        if (bankRowCount > 0 && infoRowCount > 0) {
            //表格第二行
            mergeCell(2, 1, 2 + bankRowCount, 1);
            mergeCell(2, 2, 2, 3);
            mergeCell(2, 3, 2, 5);
            mergeCell(2, 4, 2, 5);
            mergeCell(2, 5, 2, 7);
            for (int i = 3; i < 3 + bankRowCount; i++) {
                mergeCell(i, 2, i, 3);
                mergeCell(i, 3, i, 5);
                mergeCell(i, 4, i, 5);
                mergeCell(i, 5, i, 7);
            }

            /****************/
            goToBegin();
            putTxtToCell(2, 2, 1, "涉\r\n案\r\n资\r\n金\r\n流");
            putTxtToCell(2, 2, 2, "银行名称");
            putTxtToCell(2, 2, 3, "账号编码");
            putTxtToCell(2, 2, 5, "资金流反馈");
            putTxtToCell(2, 2, 4, "止付余额");
            putTxtToCell(2, 2, 6, "中国银联");
            putTxtToCell(2, 2, 7, "查控平台");
            for (int i = 6; i < alarmBankData.size(); i++) {
                HashMap<String, String> alarmBankInfo = alarmBankData.get(i);
                putTxtToCell(2, i - 3, 2, alarmBankInfo.get("bank_name"));
                putTxtToCell(2, i - 3, 3, alarmBankInfo.get("bank_number"));
                putTxtToCell(2, i - 3, 5, alarmBankInfo.get("bank_fruit"));
                putTxtToCell(2, i - 3, 4, alarmBankInfo.get("bank_money"));
                putTxtToCell(2, i - 3, 6, alarmBankInfo.get("CUP"));
                putTxtToCell(2, i - 3, 7, alarmBankInfo.get("chaKong"));
            }
            mergeCell(3 + bankRowCount, 1, 3 + bankRowCount + infoRowCount, 1);
            mergeCell(3 + bankRowCount, 2, 3 + bankRowCount, 3);
            mergeCell(3 + bankRowCount, 3, 3 + bankRowCount, 5);
            mergeCell(3 + bankRowCount, 4, 3 + bankRowCount, 7);
            mergeCell(3 + bankRowCount, 5, 3 + bankRowCount, 7);

            for (int i = 4 + bankRowCount; i < tableRowCount; i++) {
                mergeCell(i, 2, i, 3);
                mergeCell(i, 3, i, 5);
                mergeCell(i, 4, i, 7);
                mergeCell(i, 5, i, 7);
            }

            putTxtToCell(2, 3 + bankRowCount, 1, "涉\r\n案\r\n信\r\n息\r\n流");
            putTxtToCell(2, 3 + bankRowCount, 2, "运营商名");
            putTxtToCell(2, 3 + bankRowCount, 3, "号码/地址");
            putTxtToCell(2, 3 + bankRowCount, 4, "信息流反馈");
            putTxtToCell(2, 3 + bankRowCount, 5, "三侦反馈");

            for (int i = 4; i < alarmInfoData.size(); i++) {
                HashMap<String, String> alarmInfo = alarmInfoData.get(i);
                putTxtToCell(2, i + bankRowCount, 2, alarmInfo.get("info_name"));
                putTxtToCell(2, i + bankRowCount, 3, alarmInfo.get("phone_number"));
                putTxtToCell(2, i + bankRowCount, 4, alarmInfo.get("info_fruit"));
                putTxtToCell(2, i + bankRowCount, 5, alarmInfo.get("three_fruit"));
            }
        }

        mergeCell(tableRowCount, 2, tableRowCount, 13);

        putTxtToCell(2, tableRowCount, 1, "备注:");

    }


    /**
     * 填充资金流通知书的表格数据
     *
     * @param data
     */
    public void addCapitalFlowData(HashMap<String, Object> data) {
        ArrayList<HashMap<String, String>> capitalFlowData = (ArrayList<HashMap<String, String>>) data.get("${capitalFlowData}");

        for (int i = 0; i < (capitalFlowData.size() > 3 ? 3 : capitalFlowData.size()); i++) {
            HashMap<String, String> capitalFlowInfo = capitalFlowData.get(i);
            putTxtToCell(1, i + 5, 1, capitalFlowInfo.get("id"));
            putTxtToCell(1, i + 5, 2, capitalFlowInfo.get("bank_number"));
            putTxtToCell(1, i + 5, 3, capitalFlowInfo.get("bank_time"));
            putTxtToCell(1, i + 5, 5, capitalFlowInfo.get("bank_desc"));
        }

        int tableRowCount = capitalFlowData.size() - 3 + 3;

        if (capitalFlowData.size() > 3) {
            selection = Dispatch.get(word, "Selection").toDispatch();
            insertNewPageToEnd();
            goToEnd();
            insertText("附：表二部分（接上表内容）\r\n");
            goToBegin();
            goToEnd();

        /*添加表格*/
            insertText("${table}");
            goToBegin();
            createTable("${table}", 13, tableRowCount);
            table = getTable(2);

            //表格第一行
            mergeCell(1, 1, 1, 2);
            mergeCell(1, 2, 1, 6);
            mergeCell(1, 3, 1, 4);
            mergeCell(1, 4, 1, 7);
            //表格第二行
            mergeCell(2, 2, 2, 3);
            mergeCell(2, 3, 2, 4);
            mergeCell(2, 4, 2, 9);
            mergeCell(2, 5, 2, 6);

            //中间不固定行
            for (int i = 3; i < tableRowCount; i++) {
                mergeCell(i, 2, i, 3);
                mergeCell(i, 3, i, 4);
                mergeCell(i, 4, i, 9);
                mergeCell(i, 5, i, 6);
            }
            mergeCell(3, 4, tableRowCount - 1, 4);

            //最后一行
            mergeCell(tableRowCount, 1, tableRowCount, 13);

            //填充第一行数据
            putTxtToCell(2, 1, 1, "接警编号");
            String cellValue = getTxtFromCell(1, 1, 2);
            putTxtToCell(2, 1, 2, cellValue);
            putTxtToCell(2, 1, 3, "处置民警");
            cellValue = getTxtFromCell(1, 1, 4);
            putTxtToCell(2, 1, 4, cellValue);

            //填充第二行的数据
            putTxtToCell(2, 2, 1, "编号");
            putTxtToCell(2, 2, 2, "涉案银行账号");
            putTxtToCell(2, 2, 3, "起止时间");
            putTxtToCell(2, 2, 4, "处置措施名称");
            putTxtToCell(2, 2, 5, "备注");

            //填充中间不定行数据
            for (int i = 3; i < tableRowCount; i++) {
                HashMap<String, String> capitalFlowInfo = capitalFlowData.get(i);
                putTxtToCell(2, i, 1, capitalFlowInfo.get("id"));
                putTxtToCell(2, i, 2, capitalFlowInfo.get("bank_number"));
                putTxtToCell(2, i, 3, capitalFlowInfo.get("bank_time"));
                putTxtToCell(2, i, 5, capitalFlowInfo.get("bank_desc"));
            }
            cellValue = getTxtFromCell(1, 5, 4);
            putTxtToCell(2, 3, 4, cellValue);

            //填充最后一行的数据
            cellValue = getTxtFromCell(1, 8, 1);
            putTxtToCell(2, tableRowCount, 1, cellValue);
        }

    }



    /**
     * 填充第三方支付数据
     *
     * @param data
     */
    private void addPayData(HashMap<String, Object> data) {
        ArrayList<HashMap<String, String>> payData = (ArrayList<HashMap<String, String>>) data.get("${payData}");

        for (int i = 0; i < (payData.size() > 3 ? 3 : payData.size()); i++) {
            HashMap<String, String> payInfo = payData.get(i);
            putTxtToCell(1, i + 5, 1, payInfo.get("id"));
            putTxtToCell(1, i + 5, 2, payInfo.get("pay_type"));
            putTxtToCell(1, i + 5, 3, payInfo.get("pay_time"));
            putTxtToCell(1, i + 5, 4, payInfo.get("pay_number"));
            putTxtToCell(1, i + 5, 5, payInfo.get("pay_numberType"));
            putTxtToCell(1, i + 5, 6, payInfo.get("pay_desc"));
        }

        int tableRowCount = payData.size() - 3 + 3;

        if (payData.size() > 3) {
            selection = Dispatch.get(word, "Selection").toDispatch();
            insertNewPageToEnd();
            goToEnd();
            insertText("附：表二部分（接上表内容）\r\n");
            goToBegin();
            goToEnd();

        /*添加表格*/
            insertText("${table}");
            goToBegin();
            createTable("${table}", 13, tableRowCount);
            table = getTable(2);

            //合并第一行
            mergeCell(1, 1, 1, 2);
            mergeCell(1, 2, 1, 5);
            mergeCell(1, 3, 1, 5);
            mergeCell(1, 4, 1, 7);

            //合并不固定行
            for (int i = 2; i < tableRowCount; i++) {
                mergeCell(i, 2, i, 3);
                mergeCell(i, 3, i, 4);
                mergeCell(i, 4, i, 6);
                mergeCell(i, 5, i, 7);
                mergeCell(i, 6, i, 7);
            }

            //合并最后一行
            mergeCell(tableRowCount, 1, tableRowCount, 13);

            //填充第一行数据
            putTxtToCell(2, 1, 1, "接警编号");
            String cellValue = getTxtFromCell(1, 1, 2);
            putTxtToCell(2, 1, 2, cellValue);
            putTxtToCell(2, 1, 3, "处置民警");
            cellValue = getTxtFromCell(1, 1, 4);
            putTxtToCell(2, 1, 4, cellValue);

            //填充第二行数据
            putTxtToCell(2, 2, 1, "序号");
            putTxtToCell(2, 2, 2, "类型");
            putTxtToCell(2, 2, 3, "协作起止时间");
            putTxtToCell(2, 2, 4, "编号/代码/账号");
            putTxtToCell(2, 2, 5, "号码属性");
            putTxtToCell(2, 2, 6, "备注");

            for (int i = 3; i < tableRowCount; i++) {
                HashMap<String, String> payInfo = payData.get(i);
                putTxtToCell(2, i, 1, payInfo.get("id"));
                putTxtToCell(2, i, 2, payInfo.get("pay_type"));
                putTxtToCell(2, i, 3, payInfo.get("pay_time"));
                putTxtToCell(2, i, 4, payInfo.get("pay_number"));
                putTxtToCell(2, i, 5, payInfo.get("pay_numberType"));
                putTxtToCell(2, i, 6, payInfo.get("pay_desc"));
            }

            cellValue = getTxtFromCell(1, 9, 1);
            putTxtToCell(2, tableRowCount, 1, cellValue);
        }
    }

    public void addDataToTableInCenter(ArrayList<String[]> tableData, int tableIndex, String text) {
        if (tableData.size() < 1) {
            return;
        }
        //创建表格行
        for (int i = 0; i < tableData.size(); i++) {
            addRow(tableIndex);
        }
        //为每一单元格填充数据
        for (int i = 0; i < tableData.size(); i++) {
            String[] rowData = tableData.get(i);
            for (int j = 0; j < rowData.length; j++) {
                putTxtToCell(tableIndex, i + 3, j + 1, rowData[j]);
            }
        }
        addRow(tableIndex);
        if (selection == null) {
            selection = Dispatch.get(word, "Selection").toDispatch();
        }
        this.table = getTable(tableIndex);
        mergeCell(tableData.size() + 3, 1, tableData.size() + 3, tableData.get(0).length);
        putTxtToCell(tableIndex, tableData.size() + 3, 1, text);
    }

    /**
     * 月报添加数据到表格
     *
     * @param tableData
     */
    public void addDataToTable(ArrayList<String[]> tableData, int tableIndex) {
        if (tableData.size() < 1) {
            return;
        }
        //创建表格行
        for (int i = 0; i < tableData.size(); i++) {
            addRow(tableIndex);
        }
        //为每一单元格填充数据
        for (int i = 0; i < tableData.size(); i++) {
            String[] rowData = tableData.get(i);
            for (int j = 0; j < rowData.length; j++) {
                putTxtToCell(tableIndex, i + 2, j + 1, rowData[j]);
            }
        }
    }

    public void addDataToTableInCenterDay(ArrayList<String[]> tableData, int tableIndex) {
        if (tableData.size() < 1) {
            return;
        }
        //创建表格行
        for (int i = 0; i < tableData.size(); i++) {
            addRow(tableIndex);
        }
        //为每一单元格填充数据
        for (int i = 0; i < tableData.size(); i++) {
            String[] rowData = tableData.get(i);
            for (int j = 0; j < rowData.length; j++) {
                putTxtToCell(tableIndex, i + 3, j + 1, rowData[j]);
            }
        }
    }
}
